package com.yexx.nacos.controller;

import com.yexx.limit.annotation.RequestLimit;
import com.yexx.lock.DistributedLocker;
import com.yexx.nacos.api.DiscoveryApi;
import com.yexx.nacos.entity.OrderDO;
import com.yexx.nacos.service.OrderService;
import com.yexx.uid.IdGenerator;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.StringTokenizer;
import java.util.concurrent.*;

/**
 * Description: 消费者
 *
 * @author: zuomin (myleszelic@outlook.com)
 * @date: 2020/08/12-10:39
 */
@Slf4j
@RestController
@RequestMapping("/api/discovery")
public class DiscoveryController {

    @Resource
    DiscoveryApi discoveryApi;

    @Autowired
    private OrderService orderService;

    @Autowired
    IdGenerator idGenerator;

    @Autowired
    DistributedLocker distributedLocker;

    static ExecutorService executorService = Executors.newFixedThreadPool(10);

    @GetMapping("/get")
    @Transactional
    @GlobalTransactional
    public String get(String serviceName) {

        OrderDO orderDO = OrderDO.builder().id(1L).commodityCode("00001").count(1L).money(100L).userId("myleszelic").build();
        orderService.update(orderDO);
        // feign 调用
        String s = discoveryApi.get(serviceName);
        return s;
    }

    @GetMapping("/uid")
    public Long get() {
        return idGenerator.generate();
    }

    @GetMapping("/lock")
    @RequestLimit
    public void lock() {
        int max = 10;
        final Semaphore semaphore = new Semaphore(10);
        for (int i = 0; i < max; i++) {
            executorService.execute(() ->  {
                    try {
                        semaphore.acquire();
                        ABC();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    semaphore.release();
            });
        }
    }

    int cnt = 0;

    public void ABC() {
        try {
            log.info(LocalDateTime.now().toString());
            log.info("开始上锁");
//            boolean abc = luaDistributedLocker.lock("abc", requestId, 2);
            boolean abc = distributedLocker.lock("abc");
            if (abc) {
                String requestId = idGenerator.generate().toString();
                log.info("-------------------------" + cnt++ + "----------" + requestId);
                log.info("开始执行业务代码,需要1ms才能走完");
                log.info("结束执行业务代码");
            }
        } finally {
            distributedLocker.unlock("abc");
            log.info("解锁");
        }
    }


    public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {
       /* CompletableFuture<Object> exceptionally = CompletableFuture.supplyAsync(() -> {
            int i = 1 / 0;
            return null;
        }, executorService).exceptionally(e -> {
            e.printStackTrace();
            return null;
        });
        CompletableFuture.allOf(exceptionally);
        Object o = exceptionally.get(3, TimeUnit.SECONDS );*/

        String a = "zhangsan,lisi,wangwu";
        StringTokenizer tokenizer = new StringTokenizer(a, ", ");
        int count = tokenizer.countTokens();
        while (tokenizer.hasMoreTokens()){
            System.out.println(tokenizer.nextToken());
        }




        int i = 100000;


    }




}
